package com.xc.ezplan.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xc.ezplan.admin.entity.AdminJob;
import com.xc.ezplan.admin.entity.AdminRole;
import com.xc.ezplan.admin.entity.AdminUsersJobs;
import com.xc.ezplan.admin.mapper.AdminUsersJobsMapper;
import com.xc.ezplan.admin.service.AdminJobService;
import com.xc.ezplan.admin.mapper.AdminJobMapper;
import com.xc.ezplan.admin.vo.AdminJobVo;
import com.xc.ezplan.admin.vo.AdminRoleVo;
import com.xc.ezplan.cache.constants.RedisKey;
import com.xc.ezplan.cache.utils.CacheUtil;
import com.xc.ezplan.cache.utils.RedisUtils;
import com.xc.ezplan.core.base.SearchCondition;
import com.xc.ezplan.core.exception.BadRequestException;
import com.xc.ezplan.core.exception.EntityExistException;
import com.xc.ezplan.core.utils.FileUtil;
import com.xc.ezplan.core.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * @author lixingchen
 * @date 2022/11/19
 * @description 岗位管理实现类
 */
@Service
@Primary
@RequiredArgsConstructor
@CacheConfig(cacheNames = "job")
public class AdminJobServiceImpl extends ServiceImpl<AdminJobMapper, AdminJob> implements AdminJobService {

	private final AdminJobMapper adminJobMapper;

	private final AdminUsersJobsMapper adminUsersJobsMapper;
	private final RedisUtils redisUtils;

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void createJob(AdminJobVo adminJobVo) {
		if (Objects.nonNull(adminJobMapper
				.selectOne(new QueryWrapper<AdminJob>().lambda().eq(AdminJob::getName, adminJobVo.getName())))) {
			throw new EntityExistException(AdminJob.class, "name", adminJobVo.getName());
		}
		AdminJob adminJob = new AdminJob();
		BeanUtils.copyProperties(adminJobVo, adminJob);
		adminJobMapper.insert(adminJob);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void deleteJob(List<Long> ids) {
		// 验证是否被用户关联
		if (adminUsersJobsMapper
				.selectCount(new QueryWrapper<AdminUsersJobs>().lambda().in(AdminUsersJobs::getJobId, ids)) > 0) {
			throw new BadRequestException("所选的岗位中存在用户关联，请解除关联再试！");
		}
		adminJobMapper.delete(new QueryWrapper<AdminJob>().lambda().in(AdminJob::getId, ids));
		CacheUtil.deleteCache(RedisKey.JOB_ID,ids);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateJob(AdminJobVo adminJobVo) {
		// 验证是否重名
		if (adminJobMapper.selectCount(new QueryWrapper<AdminJob>().lambda().eq(AdminJob::getName, adminJobVo.getName())
				.ne(AdminJob::getId, adminJobVo.getId())) > 0) {
			throw new EntityExistException(AdminJob.class, "name", adminJobVo.getName());
		}
		AdminJob adminJob = new AdminJob();
		BeanUtils.copyProperties(adminJobVo, adminJob);
		adminJobMapper.update(adminJob,new UpdateWrapper<AdminJob>().lambda().eq(AdminJob::getId,adminJobVo.getId()));
		CacheUtil.deleteCache(RedisKey.JOB_ID,adminJobVo.getId());
	}

	@Override
	public Object pageQueryJob(SearchCondition searchCondition, Page<AdminJob> page) {
		List<Date> createTime = searchCondition.getCreateTime();
		LambdaQueryWrapper<AdminJob> queryWrapper = new QueryWrapper<AdminJob>().lambda().like(
				StringUtils.isNotBlank(searchCondition.getKeyWord()), AdminJob::getName, searchCondition.getKeyWord());
		if (!CollectionUtils.isEmpty(createTime) && createTime.size() == 2) {
			queryWrapper.between(AdminJob::getCreateTime, createTime.get(0), createTime.get(1));
		}
		return adminJobMapper.selectPage(page, queryWrapper);
	}

	@Override
	public void exportJob(HttpServletResponse response, List<AdminJobVo> adminJobVos) throws IOException {
		List<Map<String, Object>> list = new ArrayList<>();
		for (AdminJobVo adminJobVo : adminJobVos) {
			Map<String,Object> map = new LinkedHashMap<>();
			map.put("岗位名称", adminJobVo.getName());
			map.put("岗位状态", adminJobVo.getEnabled() ? "启用" : "停用");
			map.put("创建日期", adminJobVo.getCreateTime());
			list.add(map);
		}
		FileUtil.downloadExcel(list);
	}

	@Override
	@Cacheable(key = "'id:' + #p0")
	public Object findJobById(Long jobId) {
		AdminJobVo adminJobVo = new AdminJobVo();
		if (jobId != null) {
			AdminJob adminJob = adminJobMapper
					.selectOne(new QueryWrapper<AdminJob>().lambda().eq(AdminJob::getId, jobId));
			BeanUtils.copyProperties(adminJob, adminJobVo);
		}
		return adminJobVo;
	}

}
